Using the super Keyword and Constructor Chaining in Java
Course: Core Java Training
Topic: Using the super Keyword and Constructor Chaining
Course Link: Core Java Training Course
Demo Link: Register for a Course Demo
Website: JustAcademy
1. Introduction
In Java, inheritance allows one class to acquire accessible members from another class. When working with inheritance, developers often need to initialize parent-class data, call inherited behavior, and coordinate the initialization of objects across multiple classes. Java provides the super keyword and constructor chaining to help accomplish these tasks.
The super keyword refers to the superclass portion of the current object. It can be used to invoke a superclass constructor, call an inherited method implementation, or access a superclass field hidden by a field declared in the subclass.
Constructor chaining is the process of calling one constructor from another constructor, either within the same class or through a superclass. It helps reuse initialization logic and ensures that superclass state is initialized as part of constructing a subclass object.
Learning Objectives
- Understand the purpose and uses of the
super keyword.
- Learn how to call superclass constructors with
super().
- Understand the difference between
this() and super().
- Learn how constructors execute in an inheritance hierarchy.
- Implement constructor chaining using single and multilevel inheritance.
- Identify common constructor errors and follow best practices.
2. What Is the super Keyword?
The super keyword is used within a subclass to refer to superclass members. It is particularly useful when a subclass overrides a method, declares a field with the same name as a superclass field, or needs to initialize superclass data through a constructor.
Consider a parent class named Animal and a child class named Dog. The Dog class may have its own implementation of a method such as makeSound(). If it needs to execute the original implementation from Animal, it can call super.makeSound().
Main Uses of super
- Calling a superclass constructor: Use
super() or super(arguments).
- Calling a superclass method: Use
super.methodName().
- Accessing a hidden superclass field: Use
super.fieldName when a subclass field hides a field with the same name.
3. Using super to Call a Superclass Constructor
A subclass constructor can invoke a constructor of its direct superclass by using super(). If the superclass constructor requires arguments, those arguments are supplied inside the parentheses.
Syntax
class Parent {
Parent() {
System.out.println("Parent constructor");
}
}
class Child extends Parent {
Child() {
super();
System.out.println("Child constructor");
}
}
In this example, super() invokes the no-argument constructor of Parent before the body of the Child constructor executes.
Output
Parent constructor
Child constructor
For traditional Java constructor syntax, an explicit super(...) invocation appears at the beginning of the constructor body. Java 25 and later also support flexible constructor bodies, which permit certain statements before an explicit constructor invocation subject to language restrictions. For typical Core Java programs, using super(...) as the first statement remains a clear and widely compatible practice.
4. Calling a Parameterized Superclass Constructor
Sometimes a superclass needs information to initialize its fields. In that situation, the subclass can pass values to a parameterized superclass constructor using super(arguments).
Example
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
System.out.println("Person constructor executed.");
}
}
class Student extends Person {
int rollNumber;
Student(String name, int age, int rollNumber) {
super(name, age);
this.rollNumber = rollNumber;
System.out.println("Student constructor executed.");
}
void display() {
System.out.println("Name: " + name);
System.out.println("Age: " + age);
System.out.println("Roll Number: " + rollNumber);
}
}
public class SuperConstructorDemo {
public static void main(String[] args) {
Student student = new Student("Aarav", 20, 101);
student.display();
}
}
Output:
Person constructor executed.
Student constructor executed.
Name: Aarav
Age: 20
Roll Number: 101
Explanation
Person defines a constructor that accepts a name and age.
Student extends Person and adds a roll number.
- The
super(name, age) statement passes the values to the superclass constructor.
- The superclass initializes its fields before the subclass constructor continues.
- The subclass initializes its own
rollNumber field after the superclass constructor call.
5. Using super to Call a Parent Method
A subclass can override a superclass method and still invoke the original superclass implementation using super.methodName(). This is useful when the child class needs to preserve existing behavior and add extra functionality.
Example
class Employee {
void displayRole() {
System.out.println("General employee.");
}
}
class Manager extends Employee {
@Override
void displayRole() {
super.displayRole();
System.out.println("Manages a team.");
}
}
public class SuperMethodDemo {
public static void main(String[] args) {
Manager manager = new Manager();
manager.displayRole();
}
}
Output:
General employee.
Manages a team.
Explanation
Employee defines the original displayRole() method.
Manager overrides that method with additional behavior.
super.displayRole() invokes the superclass implementation.
- The statement following the superclass call prints the manager-specific information.
6. Using super to Access a Hidden Field
A field declared in a subclass can have the same name as a field in its superclass. This is called field hiding. Within the subclass, the superclass field can be referenced using super.fieldName.
Example
class Parent {
String message = "Message from Parent";
}
class Child extends Parent {
String message = "Message from Child";
void displayMessages() {
System.out.println(message);
System.out.println(super.message);
}
}
public class SuperFieldDemo {
public static void main(String[] args) {
Child child = new Child();
child.displayMessages();
}
}
Output:
Message from Child
Message from Parent
The first statement accesses the field declared in Child. The second explicitly accesses the field declared in Parent.
Best practice: Avoid declaring fields with the same name in a parent and child class unless there is a specific reason. Field hiding can make programs harder to understand.
7. What Is Constructor Chaining?
Constructor chaining is the process of one constructor invoking another constructor as part of object initialization. In Java, constructor chaining can happen in two main ways:
- Within the same class: One constructor invokes another constructor using
this(...).
- Across a class hierarchy: A subclass constructor invokes its direct superclass constructor using
super(...).
Constructor chaining reduces duplicate initialization code and helps ensure that each class initializes its own data correctly.
Basic Constructor Chaining Structure
class A {
A() {
System.out.println("A constructor");
}
}
class B extends A {
B() {
super();
System.out.println("B constructor");
}
}
class C extends B {
C() {
super();
System.out.println("C constructor");
}
}
When a C object is created, Java initializes the superclass hierarchy from the highest relevant superclass down to the subclass.
8. Constructor Chaining Within the Same Class Using this()
The this() constructor invocation calls another constructor in the same class. It is useful when several constructors share common initialization logic.
Example
class Product {
String name;
double price;
Product() {
this("Unknown", 0.0);
System.out.println("Default constructor executed.");
}
Product(String name, double price) {
this.name = name;
this.price = price;
System.out.println("Parameterized constructor executed.");
}
void display() {
System.out.println("Product: " + name);
System.out.println("Price: " + price);
}
}
public class ThisConstructorDemo {
public static void main(String[] args) {
Product product = new Product();
product.display();
}
}
Output:
Parameterized constructor executed.
Default constructor executed.
Product: Unknown
Price: 0.0
Explanation
- The no-argument constructor calls
this("Unknown", 0.0).
- The parameterized constructor initializes the fields.
- After the parameterized constructor returns, the no-argument constructor continues executing.
- The shared initialization logic is written once instead of being duplicated.
A constructor that uses this(...) must not create a direct or indirect cycle by calling itself through other constructors.
9. Difference Between this() and super()
Both this() and super() are used for constructor invocation, but they have different purposes.
| Basis |
this() |
super() |
| Purpose |
Calls another constructor in the same class. |
Calls a constructor in the direct superclass. |
| Primary use |
Reuses initialization logic among constructors of one class. |
Initializes the superclass portion of a subclass object. |
| Arguments |
Must match a suitable constructor in the current class. |
Must match an accessible constructor in the direct superclass. |
| Inheritance requirement |
Does not require inheritance. |
Used when invoking a superclass constructor. |
| Constructor chaining |
Chains constructors within the same class. |
Chains constructors across the inheritance hierarchy. |
| Placement |
Must be used as the explicit constructor invocation in its permitted position. |
Must be used as the explicit superclass constructor invocation in its permitted position. |
Important: A constructor cannot explicitly invoke both this(...) and super(...) as separate constructor-invocation statements. Calling another constructor using this(...) delegates the superclass initialization through that constructor's chain.
10. Understanding Constructor Execution Order
When a subclass object is created, Java initializes the superclass portion of the object before completing the subclass constructor body. In a multilevel inheritance hierarchy, this process continues through the superclass chain.
Example
class A {
A() {
System.out.println("Constructor A");
}
}
class B extends A {
B() {
super();
System.out.println("Constructor B");
}
}
class C extends B {
C() {
super();
System.out.println("Constructor C");
}
}
public class ConstructorOrderDemo {
public static void main(String[] args) {
C obj = new C();
}
}
Output:
Constructor A
Constructor B
Constructor C
Execution Steps
- The program creates an object of class
C.
- The
C constructor invokes the B constructor.
- The
B constructor invokes the A constructor.
- The
A constructor executes first.
- After
A completes, the remaining body of B executes.
- Finally, the remaining body of
C executes.
This ordering allows each superclass to initialize its part of the object before the subclass completes its own initialization.
11. Complete Example: Multilevel Constructor Chaining
This practical example uses a three-level hierarchy to demonstrate how constructor arguments are passed through successive superclass constructors.
class Person {
String name;
Person(String name) {
this.name = name;
System.out.println("Person initialized.");
}
}
class Employee extends Person {
int employeeId;
Employee(String name, int employeeId) {
super(name);
this.employeeId = employeeId;
System.out.println("Employee initialized.");
}
}
class Manager extends Employee {
String department;
Manager(String name, int employeeId, String department) {
super(name, employeeId);
this.department = department;
System.out.println("Manager initialized.");
}
void display() {
System.out.println("Name: " + name);
System.out.println("Employee ID: " + employeeId);
System.out.println("Department: " + department);
}
}
public class MultilevelChainingDemo {
public static void main(String[] args) {
Manager manager = new Manager(
"Priya", 205, "Engineering"
);
manager.display();
}
}
Output:
Person initialized.
Employee initialized.
Manager initialized.
Name: Priya
Employee ID: 205
Department: Engineering
Explanation
Person initializes the employee's name.
Employee invokes super(name) and initializes the employee ID.
Manager invokes super(name, employeeId) and initializes the department.
- The constructor chain ensures that each class initializes the data it owns.
- The final object contains the state and behavior defined across the hierarchy.
12. What Happens If super() Is Not Written?
If a constructor does not explicitly invoke another constructor using this(...) or super(...), Java normally inserts an implicit no-argument superclass constructor invocation where the language rules permit it.
Example
class Parent {
Parent() {
System.out.println("Parent constructor");
}
}
class Child extends Parent {
Child() {
System.out.println("Child constructor");
}
}
public class ImplicitSuperDemo {
public static void main(String[] args) {
new Child();
}
}
Output:
Parent constructor
Child constructor
The Child() constructor does not explicitly contain super(), but Java inserts the implicit call to the no-argument constructor of Parent.
Important Case: No Default Constructor in the Parent
class Parent {
Parent(String name) {
System.out.println(name);
}
}
class Child extends Parent {
Child() {
super("Java");
}
}
Here, Child explicitly invokes the parameterized constructor of Parent. If the super("Java") statement were omitted, the compiler would attempt to use a no-argument superclass constructor, which does not exist, and the code would fail to compile.
13. Constructor Chaining and Field Initialization
Java initializes instance fields with their default values and then performs instance field initializers and instance initialization blocks as part of object construction. Constructor chaining coordinates superclass and subclass initialization. Understanding the order is important when constructors depend on field values.
For typical programs, remember these points:
- Instance fields receive default values such as
0, false, or null before explicit initialization.
- Superclass construction takes place before the subclass constructor body completes.
- Instance field initializers and initialization blocks execute as part of the initialization process for their respective classes.
- Use constructors to establish valid initial state.
- Avoid calling overridable methods from constructors when possible, because a subclass implementation may execute before the subclass has completed its initialization.
14. Common Errors When Using super and Constructor Chaining
| Error |
Cause |
Solution |
| Constructor cannot be applied to given types |
The arguments passed to super(...) do not match an accessible superclass constructor. |
Check the superclass constructor signature and pass compatible arguments. |
| Implicit super constructor is undefined |
The superclass has no accessible no-argument constructor. |
Invoke an available superclass constructor explicitly using super(arguments). |
| Constructor call must be first |
In traditional constructor syntax, statements appear before an explicit this(...) or super(...) call. |
Place the constructor invocation in the permitted position. Java 25 and later have additional flexible constructor-body rules. |
| Recursive constructor invocation |
Constructors call one another in a cycle using this(...). |
Redesign the constructor chain so that it eventually reaches a constructor that initializes the object without repeating the cycle. |
| Cannot reference this before supertype constructor |
The constructor uses the current instance before the required superclass construction step has been completed. |
Move instance-dependent operations until after the superclass constructor invocation. |
| Unexpected constructor output order |
The programmer assumes subclass constructors execute before superclass constructors. |
Trace the constructor chain from the superclass level toward the subclass level. |
15. Best Practices for super and Constructor Chaining
- Use
super(...) to initialize superclass fields through the appropriate constructor.
- Use
this(...) to reuse constructor logic within the same class.
- Avoid duplicating the same field-initialization logic in multiple constructors.
- Ensure that each constructor establishes a valid object state.
- Use the most suitable constructor rather than relying on a no-argument constructor that does not represent valid initialization.
- Keep constructor chains easy to follow and avoid circular calls between constructors.
- Use
super.methodName() only when the superclass implementation is needed.
- Avoid unnecessary field hiding because it can make code confusing.
- Avoid calling overridable methods from constructors unless the implications are fully understood.
- Test constructor behavior for valid arguments, invalid arguments, and different constructor overloads.
16. Practical Exercises
- Person and Student: Create a
Person class with a parameterized constructor. Extend it with Student and initialize the parent fields using super().
- Vehicle and Car: Create a
Vehicle constructor that accepts a brand. Extend it with Car, pass the brand to the superclass, and initialize the number of doors.
- Constructor overloading: Create a
Product class with default and parameterized constructors. Use this() to reuse initialization logic.
- Three-level hierarchy: Create
Person, Employee, and Manager classes. Print a message from each constructor to observe the execution order.
- Superclass method: Create a parent class with a
display() method and override it in a child class. Use super.display() to execute both implementations.
- Constructor validation: Validate input in a superclass constructor and ensure that the subclass passes appropriate values through
super(...).
17. Mini Project: Vehicle Registration System
Objective: Build a simple Java program that uses inheritance, the super keyword, and constructor chaining to initialize vehicle information.
Requirements
- Create a
Vehicle class with fields for brand and registration number.
- Provide a parameterized constructor to initialize these fields.
- Create a
Car subclass with an additional field for the number of doors.
- Use
super(brand, registrationNumber) to initialize the superclass fields.
- Create a
ElectricCar subclass with a battery capacity field.
- Use constructor chaining across all three levels.
- Display all vehicle details using appropriate methods.
- Validate that registration numbers and numeric values meet the program's requirements.
Expected Learning Outcomes
After completing the project, learners should understand how to pass constructor arguments across an inheritance hierarchy, reuse superclass initialization, and keep class-specific initialization in the appropriate constructor.
18. Core Java Interview Questions and Answers
Q1. What is the super keyword in Java?
Answer: The super keyword refers to the superclass portion of the current object. It can be used to call superclass constructors, invoke superclass methods, and access hidden superclass fields.
Q2. What is constructor chaining?
Answer: Constructor chaining is the process of one constructor invoking another constructor in the same class or a superclass to coordinate object initialization.
Q3. What is the difference between this() and super()?
Answer: this() invokes another constructor in the same class, while super() invokes a constructor in the direct superclass.
Q4. Why is super() used in a subclass constructor?
Answer: It invokes the superclass constructor so that the superclass portion of the object can be initialized with appropriate values.
Q5. What happens if super() is omitted?
Answer: Java normally inserts an implicit no-argument superclass constructor invocation if the constructor does not explicitly invoke another constructor and an accessible no-argument superclass constructor is available.
Q6. Can this() and super() both be used as separate calls in one constructor?
Answer: No. A constructor cannot contain both as separate explicit constructor-invocation statements. A constructor that calls this(...) delegates the superclass construction through the constructor it invokes.
Q7. Can a subclass call a parameterized superclass constructor?
Answer: Yes. It can use super(arguments) with arguments that match an accessible constructor in the direct superclass.
Q8. Can super be used to call an overridden method?
Answer: Yes. A subclass can use super.methodName() to invoke the superclass implementation of an overridden method.
Q9. Are constructors inherited in Java?
Answer: No. Constructors are not inherited. A subclass constructor invokes an appropriate superclass constructor as part of object initialization.
Q10. What is multilevel constructor chaining?
Answer: It occurs when a constructor in a subclass invokes its superclass constructor, which in turn invokes the next superclass constructor, continuing up the hierarchy.
Q11. Can super be used in a static method?
Answer: No. The ordinary forms of super that refer to the current object's superclass members require an instance context and cannot be used in a static method.
Q12. Why should overridable methods generally be avoided in constructors?
Answer: An overridden subclass implementation may execute before the subclass has completed initialization, potentially accessing fields that are not yet ready.
19. Quick Revision Notes
super() calls a superclass constructor.
super(arguments) calls a matching parameterized superclass constructor.
super.methodName() invokes a superclass method implementation.
super.fieldName accesses a hidden superclass field.
this() invokes another constructor in the same class.
- Constructor chaining supports code reuse and structured initialization.
- Superclass construction occurs before the subclass constructor body completes.
- Constructors are not inherited.
- If a superclass lacks an accessible no-argument constructor, the subclass must invoke an appropriate constructor explicitly.
- A constructor chain must not contain a recursive cycle.
- Use constructors to establish valid initial state and avoid unnecessary initialization duplication.
20. Conclusion
The super keyword and constructor chaining are important Core Java concepts for working with inheritance. The super keyword allows subclasses to invoke superclass constructors, access hidden fields, and reuse superclass method implementations. Constructor chaining allows related constructors to share initialization logic and ensures that each class in an inheritance hierarchy initializes its own state.
Practice these concepts with person, student, employee, manager, and vehicle examples. Focus on understanding the difference between this() and super(), constructor execution order, parameter passing, and the rules governing constructor calls.
Continue Learning with JustAcademy
Explore the Core Java Training Course to continue learning Java fundamentals, constructors, inheritance, polymorphism, and object-oriented programming.
Register for a Course Demo to learn more about the training, or visit the JustAcademy website.